package com.weixin.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/** 
 * 类描述：TODO(用一句话描述该类做什么)<br>
 * 创建人：邓强   <br>
 * 创建时间：2017年10月27日 下午2:20:06    <br> 
 * 修改人：  <br>
 * 修改时间：2017年10月27日 下午2:20:06   <br>  
 * 修改备注：     <br>
 * @version   V1.0      
 */
public class MySSLSocketFactory {
	
	/**
	  * <p>获取密钥库</p>  
	 * @param keyType   加密类型  ：PKCS12
	 * @param certPath	证书路径
	 * @param key		密钥关键字
	 * @return
	 * @throws Exception   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午2:59:46    <br>
	 */
	public static KeyManager[] getKeyManager(String keyType,String certPath, String key) throws Exception{
		return getKeyManager(keyType, certPath, keyType, "SunX509");
	}
	
	/**
	 * <p>获取密钥库</p>  
	 * @param keyType   加密类型  ：PKCS12
	 * @param certPath	证书路径
	 * @param key		密钥关键字
	 * @param keyManager	密钥库类型 ：SunX509
	 * @return
	 * @throws KeyStoreException 
	 * @throws IOException 
	 * @throws CertificateException 
	 * @throws NoSuchAlgorithmException 
	 * @throws UnrecoverableKeyException 
	 * @throws Exception   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午2:48:14    <br>
	 */
	public static KeyManager[] getKeyManager(String keyType,String certPath, String key,String keyManager) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException{
		KeyStore keyStore  = KeyStore.getInstance(keyType);
		certPath = new File(Thread.currentThread().getContextClassLoader().getResource("").getPath())+"/"+certPath;
        FileInputStream instream = new FileInputStream(certPath);
        try {
            keyStore.load(instream, key.toCharArray());
        } finally {
            instream.close();
        }

        //实例化ssl上下文

        KeyManagerFactory kmf=KeyManagerFactory.getInstance(keyManager);
        kmf.init(keyStore,key.toCharArray());  

        KeyManager[] km=kmf.getKeyManagers();
        
        return km;
	}
	
	/**
	 * <p>获取SSL套接字工厂</p>  
	 * @param agreement
	 * @param keyType
	 * @param certPath
	 * @param key
	 * @param keyManager
	 * @return
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws IOException 
	 * @throws CertificateException 
	 * @throws KeyStoreException 
	 * @throws UnrecoverableKeyException 
	 * @throws Exception   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午3:07:40    <br>
	 */
	public static SSLSocketFactory getSSLSocketFactory(String agreement,String keyType,String certPath, String key,String keyManager) throws KeyManagementException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, CertificateException, IOException{
		return getSSLSocketFactory(agreement,getKeyManager(keyType, certPath, key, keyManager));
	}
	
	/**
	 * <p>获取SSL套接字工厂</p>  
	 * @param agreement
	 * @param keyType
	 * @param certPath
	 * @param key
	 * @return
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws Exception   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午3:08:22    <br>
	 */
	public static SSLSocketFactory getSSLSocketFactory(String agreement,String keyType,String certPath, String key) throws KeyManagementException, NoSuchAlgorithmException, Exception{
		return getSSLSocketFactory(agreement,getKeyManager(keyType, certPath, key));
	}
	
	/**
	 * <p>获取SSL套接字工厂</p>  
	 * @param agreement		协议：SSL，TLS，SSLv
	 * @return
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws Exception   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午3:08:29    <br>
	 */
	public static SSLSocketFactory getSSLSocketFactory(String agreement) throws KeyManagementException, NoSuchAlgorithmException{
		return getSSLSocketFactory(agreement,null);
	}
	
	/**
	 * <p>获取SSL套接字工厂</p>  
	 * @param agreement		协议：SSL，TLS，SSLv3
	 * @param km			秘钥库
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午3:08:46    <br>
	 */
	public static SSLSocketFactory getSSLSocketFactory(String agreement,KeyManager[] km) throws KeyManagementException, NoSuchAlgorithmException{
		return getSSLSocketFactory(agreement,km,null);
	}

	/**
	 * <p>获取套接字工厂</p>  
	 * @param agreement		协议：SSL，TLS，SSLv3
	 * @param km			秘钥库
	 * @param tm			信任库
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException   
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月27日 下午2:37:19    <br>
	 */
	public static SSLSocketFactory getSSLSocketFactory(String agreement,KeyManager[] km,TrustManager[] tm) throws NoSuchAlgorithmException, KeyManagementException{

		if(tm == null){
			tm=new TrustManager[]{
					new X509TrustManager() {	//信任所有证书
						@Override
						public void checkClientTrusted(X509Certificate[] chain, String authType)
								throws CertificateException {
						}
						
						@Override
						public void checkServerTrusted(X509Certificate[] chain, String authType)
								throws CertificateException {
						}
						
						@Override
						public X509Certificate[] getAcceptedIssuers() {
							return new X509Certificate[] {};
						}
					}
				};
		}
		
		SecureRandom random=new SecureRandom();

		//实例化ssl上下文
		SSLContext sslContext = SSLContext.getInstance(agreement);
		//初始化ssl上下文(秘钥库、信任库、随机数)
		sslContext.init(km, tm, random);
		
		return sslContext.getSocketFactory();
	}
	
}
